/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-7-21 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-7-21		Created.
 ****************************************************************************
 **/
package com.me.server;

import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 
 * <br/>
 * 上午10:24:09 2012-7-21
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class JTalkPlugInloader {

	private JTalkServer theServer = null;
	private String searchURL = null;
	private JTalkPlugInInterface[] allPlugIns = null;

	public JTalkPlugInloader(JTalkServer theServer, String plugInDir) {
		this.theServer = theServer;
		if (plugInDir == null || "".equals(plugInDir)) {
			this.searchURL = "./plugins";
		} else {
			this.searchURL = plugInDir;
		}
		String[] plugIns = this.getPlugInNames();
		if (plugIns != null) {
			this.allPlugIns = new JTalkPlugInInterface[plugIns.length];
		} else {
			this.allPlugIns = null;
			return;
		}

		try {
			URL[] urlsLoadFrom = new URL[] { new File(this.searchURL).toURI().toURL() };
			URLClassLoader loader = new URLClassLoader(urlsLoadFrom);
			Class<?> tempClass = null;
			for (int i = 0; i < plugIns.length; i++) {
				tempClass = Class.forName(plugIns[i], true, loader);
				this.allPlugIns[i] = (JTalkPlugInInterface) tempClass.newInstance();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			this.allPlugIns = null;
		}

	}

	/**
	 * 获取插件的名字.
	 * 
	 * @return
	 */
	private String[] getPlugInNames() {
		File dir = new File(this.searchURL);
		FilenameFilter filter = new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".class");
			}
		};
		String[] plugIns = dir.list(filter);
		if (plugIns == null) {
			System.out.println("There is no plugins.");
			return null;
		}
		for (int i = 0; i < plugIns.length; i++) {
			plugIns[i] = plugIns[i].replace(".class", "");
		}
		return plugIns;
	}

	/**
	 * 调用插件的方法.
	 * 
	 * @param method
	 * @param caller
	 * @param commandID
	 * @return
	 */
	public synchronized String invodePlugInMethod(String method, JTalkerMember caller, String commandID) {
		// TODO Auto-generated method stub
		method = method.trim();
		String[] tempValues = method.split("::");
		String plugIn = tempValues[0];
		String tempMethod = tempValues[1];
		if (plugIn.equals("std")) {
			return invokeBuildInMethod(tempMethod, caller);
		}
		return null;
	}

	private String invokeBuildInMethod(String method, JTalkerMember caller) {
		// TODO Auto-generated method stub
		String retVal = "";
		method = method.replaceAll(" ", "");
		if (method.startsWith("createChatRoom(")) {
			// System.out.println("-----method-----" + method);
			String[] params = this.parseParams(method);
			JTalkerMember member = this.theServer.addChatRoom(params[0]); // 添加聊天室.
			String callerName = caller.getUserName();
			member.setChatRoomAdmin(callerName); // 设置聊天室管理员
			String tempUsers = params[1] + "," + callerName;
			member.setChatRoomUsers(tempUsers); // 设置聊天室用户
			this.theServer.sendUpdateRequestTo(tempUsers); // 通知用户聊天室已创建.
			retVal = "Chatroom \"" + params[0] + "\" successfull created (Op: " + member.getChatroomAdmin() + ")";
		}else if(method.startsWith("getChatRoomUsers(")){
			String[] params = this.parseParams(method);
			return this.theServer.getChatroomUsers(params[0], caller);
		}else if(method.equals("getAllUsers()")){
			return this.theServer.getAllGlobalUsers();
		}else if(method.startsWith("addChatRoomUser(")){
			String[] params = this.parseParams(method);
			if(params == null || params.length != 2){
				return "Syntax error. Try: std::addChatRoomUser(\"roomName\", \"userName\")";
			}
			if(!this.theServer.addChatRoomUser(params[0], params[1], caller)){
				return "Can't add user \"" + params[1] + "\". Wrong name or you are not the Operator!";
			} else {
				return "User added (" + params[1] + ").";
			}
		}else if(method.startsWith("removeChatRoomUser")){
			String[] params = this.parseParams(method);
			if(params == null || params.length != 2){
				return "Syntax error. Try: std::addChatRoomUser(\"roomName\", \"userName\")";
			}
			if(this.theServer.removeChatRoomUser(params[0], params[1], caller)){
				return "Can't remove user \"" + params[1] + "\". Wrong name or you are not the operator!";
			}else{
				return "User removed (" + params[1] + ").";
			}
		}else if(method.startsWith("removeChatRoom(")){
			String[] params = this.parseParams(method);
			if(params == null || params.length != 1){
				return "Syntax error. Try: std::removeChatRoom(\"roomName\")";
			}
			if(!this.theServer.removeChatroom(params[0], caller)){
				return "Can't remove chatroom \"" + params[0] + "\". Wrong name or you are not the Operator!";
			}else{
				return "Chatroom removed.";
			}
		}else if(method.equals("getMethods()")){
			retVal = "std::getRelease();;std::getAllUsers();;std::getAllPlugIns();;std::logout();;";
			retVal += "std::createChatRoom(\"roomName\", \"user1,user2,user3\");;";
			retVal += "std::removeChatRoom(\"roomName\");;";
			retVal += "std::addChatRoomUser(\"roomName\", \"userName\");;";
			retVal += "std::removeChatRoomUser(\"roomName\", \"userName\");;";
			retVal += "std::getChatRoomUsers(\"roomName\");;";
			retVal += "<PLUGIN>::getName();;";
			retVal += "<PLUGIN>::getDescription();;";
			retVal += "<PLUGIN>::getRelease();;";
			retVal += "<PLUGIN>::getMethods();;";
		}else if(method.equals("getRelease()")){
			return JTalkServer.VERSION;
		}else if(method.equals("getAllPlugIns()")){
			return this.getLoadedPlugIns();
		}else if(method.endsWith("logout()")){
			if(caller.closeSession()){
				return "Session closed.";
			}else{
				return "Can't close the session.Maybe not webclient.";
			}
		}
		return retVal;
	}

	/**
	 * 解析方法参数.
	 * @param method
	 * @return
	 */
	private String[] parseParams(String method) {
		// TODO Auto-generated method stub
		String strParams = method.substring(method.indexOf('(') + 1, method.lastIndexOf(')'));
		String[] params = strParams.split("\"[\\s]*,[\\s]*\"");
		if(params == null || params.length < 1 || (params.length == 1 && params[0].equals(""))){
			return null;
		}else{
			params[0] = params[0].replaceFirst("\"", "");
			params[params.length - 1] = params[params.length - 1].replaceFirst("\"", "");
		}
		return params;
	}

	/**
	 * 获取所有插件的名字.
	 * @return
	 */
	public String getLoadedPlugIns() {
		// TODO Auto-generated method stub
		String retVal = "";
		if(this.allPlugIns == null){
			return "";
		}
		int length = this.allPlugIns.length;
		for(int i = 0; i < length; i++){
			retVal += this.allPlugIns[i].getClass().getName();
			if(i < (length - 1)){
				retVal += ";;";
			}
		}
		return retVal;
	}

}
